home *** CD-ROM | disk | FTP | other *** search
/ MacFormat 1995 September / macformat-028.iso / mac / Shareware City / Applications / ezGenes 0.2 PPC / Source 0.2 / UFile.p < prev   
Encoding:
Text File  |  1995-06-10  |  7.8 KB  |  393 lines  |  [TEXT/MWPS]

  1. unit UFile;
  2.  
  3. interface
  4.  
  5.     uses
  6. {$IFC undefined THINK_Pascal}
  7.         TextUtils,
  8. {$ENDC}
  9.         UObject;
  10.  
  11.     type
  12.  
  13.         FileUsage = (kDisk, kPermMem, kTempMem, kClipboard);
  14.  
  15.         TGenericFile = object(TObject)
  16.  
  17.                 fref: integer;
  18.                 fSize, fPos: longint;
  19.  
  20.                 procedure TGenericFile.IGenericFile (RefNum: integer);
  21.  
  22.                 function TGenericFile.EndOfFile: Boolean;
  23.  
  24.                 procedure TGenericFile.SetFilePos (N: longint);
  25.  
  26.                 procedure TGenericFile.GetFilePos (var N: longint);
  27.  
  28.                 procedure TGenericFile.Fields (procedure DoToField (fieldName: Str255; fieldAddr: Ptr; fieldType: INTEGER));
  29.                 OVERRIDE;
  30.             end;
  31.  
  32.  
  33.         TTextFile = object(TGenericFile)
  34.  
  35.                 fBuffer: handle;
  36.                 fUsage: FileUsage;
  37.  
  38.                 procedure TTextFile.ITextFile (RefNum: integer; usage: FileUsage);
  39.  
  40.                 procedure TTextFile.Free;
  41.                 OVERRIDE;
  42.                 procedure TTextFile.ShallowRead (addr: ptr; var N: longint);    {Private}
  43.  
  44.                 procedure TTextFile.SkipTo (ch: char);
  45.  
  46.                 function TTextFile.NextLine: str255;
  47.  
  48.                 function TTextFile.NextNumber: longint;
  49.  
  50.                 procedure TTextFile.WriteLine (S: str255);
  51.  
  52.                 procedure TTextFile.SetFilePos (N: longint);
  53.                 OVERRIDE;
  54.                 procedure TTextFile.GetFilePos (var N: longint);
  55.                 OVERRIDE;
  56.                 procedure TTextFile.Fields (procedure DoToField (fieldName: Str255; fieldAddr: Ptr; fieldType: INTEGER));
  57.                 OVERRIDE;
  58.             end;
  59.  
  60.  
  61.         TRecordFile = object(TGenericFile)
  62.  
  63.                 fRecSize: integer;
  64.  
  65.                 procedure TRecordFile.IRecordFile (RefNum, RecSiz: integer);
  66.  
  67.                 procedure TRecordFile.Seek (N: longint);
  68.  
  69.                 procedure TRecordFile.ReadRec (addr: ptr);
  70.  
  71.                 procedure TRecordFile.WriteRec (addr: ptr);
  72.  
  73.                 procedure TRecordFile.Fields (procedure DoToField (fieldName: Str255; fieldAddr: Ptr; fieldType: INTEGER));
  74.                 OVERRIDE;
  75.             end;
  76.  
  77. {$IFC defined THINK_Pascal}
  78.     function TempNewHandle (logicalSize: Size; var resultCode: OSErr): Handle;
  79.     INLINE $3F3C, $001D, $A88F;
  80.  
  81.     procedure TempDisposeHandle (h: Handle; var resultCode: OSErr);
  82.     INLINE $3F3C, $0020, $A88F;
  83. {$ENDC}
  84.  
  85.  
  86. implementation
  87.  
  88.     uses
  89. {SysEqu, Traps, PrintTraps, ULoMem, UPatch, UObject, UViewCoords, UMacAppUtilities, }
  90.         UMemory, UFailure;
  91.  
  92.  
  93. {$S AFile}
  94.     procedure TGenericFile.IGenericFile (RefNum: integer);
  95.         var
  96.             N: longint;
  97.     begin
  98.         fRef := RefNum;
  99.         FailOSErr(GetEof(fRef, N));
  100.         fSize := N;
  101.         fPos := 0;
  102. {$IFC qDebug}
  103.         writeln('File: ', fSize : 6, fPos : 3);
  104. {$ENDC}
  105.     end;
  106.  
  107.     function TGenericFile.EndOfFile: Boolean;
  108.     begin
  109.         EndOfFile := (fPos >= fSize)
  110.     end;
  111.  
  112.     procedure TGenericFile.SetFilePos (N: longint);
  113.     begin
  114.         FailOSErr(SetFPos(fRef, fsFromStart, N));
  115.         fPos := N
  116.     end;
  117.  
  118.     procedure TGenericFile.GetFilePos (var N: longint);
  119.     begin
  120.         FailOSErr(GetFPos(fRef, N));
  121.         fPos := N
  122.     end;
  123.  
  124.  
  125. {  procedure TTextFile.ITextFile (RefNum: integer; Buffered: Boolean); }
  126. {   var }
  127. {    N: longint; }
  128. {  begin }
  129. {   IGenericFile(RefNum); }
  130. {   N := fSize; }
  131. {   if Buffered then }
  132. {    fBuffer := NewPermHandle(N) }
  133. {   else }
  134. {    fBuffer := nil; }
  135. {   if fBuffer <> nil then }
  136. {    FailOSErr(FSRead(fRef, N, fBuffer^)); }
  137. {  end; }
  138.  
  139.     procedure TTextFile.ITextFile (RefNum: integer; usage: FileUsage);
  140.         var
  141.             N: longint;
  142.             h: Handle;
  143.             offset: LONGINT;
  144.             savedPerm: BOOLEAN;
  145.             err: integer;
  146.     begin
  147.         fUsage := usage;
  148.         fBuffer := nil;
  149.         if usage = kClipboard then
  150.             begin
  151.                 h := NewPermHandle(0);
  152.                 FailNIL(h);
  153.                 savedPerm := PermAllocation(TRUE);
  154.                 N := GetScrap(h, 'TEXT', offset);
  155.                 savedPerm := PermAllocation(savedPerm);
  156.                 if N < 0 then
  157.                     FailOSErr(N);
  158.                 fBuffer := h;
  159.                 fRef := 0;
  160.                 fSize := N;
  161.                 fPos := 0;
  162.             end
  163.         else
  164.             begin
  165.                 IGenericFile(RefNum);
  166.                 N := fSize;
  167.                 case usage of
  168.                     kDisk: 
  169.                         ;
  170.                     kPermMem: 
  171.                         begin
  172.                             fBuffer := NewPermHandle(N);
  173. {$IFC qDebug}
  174.                             writeln('  Perm Buffer: ', MemError, fBuffer <> nil);
  175. {$ENDC}
  176.                         end;
  177.                     kTempMem: 
  178.                         begin
  179.                             if gConfiguration.systemVersion >= $700 then
  180.                                 fBuffer := TempNewHandle(N, err);
  181. {$IFC qDebug}
  182.                             writeln('  Temp Buffer: ', err, '  ', fBuffer <> nil);
  183. {$ENDC}
  184.                         end;
  185.                 end;
  186.                 if fBuffer = nil then
  187.                     fUsage := kDisk
  188.                 else
  189.                     FailOSErr(FSRead(fRef, N, fBuffer^));
  190.             end;
  191.     end;
  192.  
  193.     procedure TTextFile.Free;
  194.         OVERRIDE;
  195.         var
  196.             err: integer;
  197.     begin
  198.         case fUsage of
  199.             kDisk: 
  200.                 ;
  201.             kPermMem, kClipboard: 
  202.                 if fBuffer <> nil then
  203. {$IFC defined THINK_Pascal}
  204.                     DisposHandle(fBuffer);
  205. {$ELSEC}
  206.                     DisposeHandle(fBuffer);
  207. {$ENDC}
  208.             kTempMem: 
  209.                 begin
  210.                     TempDisposeHandle(fBuffer, err);
  211. {$IFC qDebug}
  212.                     writeln('  Disp Buffer: ', err, '  ', fBuffer = nil);
  213. {$ENDC}
  214.                 end;
  215.         end;
  216.         inherited Free;
  217.     end;
  218.  
  219. {  procedure TTextFile.Free; }
  220. {   OVERRIDE; }
  221. {  begin }
  222. {   if fBuffer <> nil then }
  223. {    DisposHandle(fBuffer); }
  224. {   inherited Free; }
  225. {  end; }
  226.  
  227.     procedure TTextFile.ShallowRead (addr: ptr; var N: longint);
  228.     begin
  229.         if fBuffer <> nil then
  230.             begin
  231.                 BlockMove(ptr(ord(fBuffer^) + fPos), addr, N);
  232.             end
  233.         else
  234.             begin
  235.                 FailOSErr(FSRead(fRef, N, addr));
  236.             end;
  237.         SetFilePos(fPos + N);
  238.     end;
  239.  
  240.     procedure TTextFile.SkipTo (ch: char);
  241.         var
  242.             S: str255;
  243.             N, p: longint;
  244.             k: integer;
  245.     begin
  246.         repeat
  247.             N := min(fSize - fPos, 255);
  248.             p := fPos;
  249.             ShallowRead(@S[1], N);
  250.             k := 0;
  251.             repeat
  252.                 k := k + 1
  253.             until (S[k] = ch) or (k = N);
  254.         until (S[k] = ch) or EndOfFile;
  255.         SetFilePos(p + k);
  256.     end;
  257.  
  258.     function TTextFile.NextLine: str255;
  259.         var
  260.             S: str255;
  261.             k, p1, p2: longint;
  262.     begin
  263.         p1 := fPos;
  264.         SkipTo(chReturn);
  265.         p2 := fPos;
  266.         k := min(p2 - p1 - 1, 255);
  267.         if k > 0 then
  268.             begin
  269.                 SetFilePos(p1);
  270.                 ShallowRead(@S[1], k);
  271.             end;
  272.         S[0] := chr(k);
  273.         NextLine := S;
  274.         SetFilePos(p2);
  275.     end;
  276.  
  277.     function TTextFile.NextNumber: longint;
  278.         var
  279.             X: str255;
  280.             k: integer;
  281.             p, N: longint;
  282.     begin
  283.         p := fPos;
  284.         X := NextLine;
  285.         k := 1;
  286.         while (k < length(X)) & (X[k] in [' ', chTab]) do
  287.             k := k + 1;
  288.         while (k < length(X)) & (X[k] in ['0'..'9']) do
  289.             k := k + 1;
  290.         X[0] := chr(k - 1);
  291.         if k > 1 then
  292.             StringToNum(X, N)
  293.         else
  294.             N := 0;
  295.         NextNumber := N;
  296.         SetFilePos(p + k - 1);
  297.     end;
  298.  
  299.     procedure TTextFile.WriteLine (S: str255);
  300.         var
  301.             N: longint;
  302.     begin
  303.         if fBuffer <> nil then
  304.             FailOSErr(111);
  305.         N := length(S);
  306.         FailOSErr(FSWrite(fRef, N, @S[1]));
  307.         N := 1;
  308.         S[1] := chReturn;
  309.         FailOSErr(FSWrite(fRef, N, @S[1]));
  310.         GetFilePos(N);
  311.         fSize := N
  312.     end;
  313.  
  314.     procedure TTextFile.SetFilePos (N: longint);
  315.         OVERRIDE;
  316.     begin
  317.         if fBuffer <> nil then
  318.             fPos := min(N, fSize)
  319.         else
  320.             inherited SetFilePos(N);
  321.     end;
  322.  
  323.     procedure TTextFile.GetFilePos (var N: longint);
  324.         OVERRIDE;
  325.     begin
  326.         if fBuffer <> nil then
  327.             N := fPos
  328.         else
  329.             inherited GetFilePos(N);
  330.     end;
  331.  
  332.  
  333.     procedure TRecordFile.IRecordFile (RefNum, RecSiz: integer);
  334.     begin
  335.         IGenericFile(RefNum);
  336.         fRecSize := RecSiz;
  337.         FailOSErr(fSize mod fRecSize);    {File size must be a multiple of record size}
  338.     end;
  339.  
  340.     procedure TRecordFile.Seek (N: longint);
  341.     begin
  342.         SetFilePos(N * fRecSize);
  343.     end;
  344.  
  345.     procedure TRecordFile.ReadRec (addr: ptr);
  346.         var
  347.             N: longint;
  348.     begin
  349.         N := fRecSize;
  350.         FailOSErr(FSRead(fRef, N, addr));
  351.         fPos := fPos + N
  352.     end;
  353.  
  354.     procedure TRecordFile.WriteRec (addr: ptr);
  355.         var
  356.             N: longint;
  357.     begin
  358.         N := fRecSize;
  359.         FailOSErr(FSWrite(fRef, N, addr));
  360.         if EndOfFile then
  361.             fSize := fSize + N;
  362.         fPos := fPos + N
  363.     end;
  364.  
  365. {$S AFields}
  366.     procedure TGenericFile.Fields (procedure DoToField (fieldName: Str255; fieldAddr: Ptr; fieldType: INTEGER));
  367.         OVERRIDE;
  368.     begin
  369.         DoToField('TGenericFile', nil, bClass);
  370.         DoToField('fRef', @fRef, bINTEGER);
  371.         DoToField('fSize', @fSize, bLongint);
  372.         DoToField('fPos', @fPos, bLongint);
  373.         inherited Fields(DoToField);
  374.     end;
  375.  
  376.     procedure TTextFile.Fields (procedure DoToField (fieldName: Str255; fieldAddr: Ptr; fieldType: INTEGER));
  377.         OVERRIDE;
  378.     begin
  379.         DoToField('TTextFile', nil, bClass);
  380.         DoToField('fBuffer', @fBuffer, bHandle);
  381.         inherited Fields(DoToField);
  382.     end;
  383.  
  384.     procedure TRecordFile.Fields (procedure DoToField (fieldName: Str255; fieldAddr: Ptr; fieldType: INTEGER));
  385.         OVERRIDE;
  386.     begin
  387.         DoToField('TRecordFile', nil, bClass);
  388.         DoToField('fRecSize', @fRecSize, bLongint);
  389.         inherited Fields(DoToField);
  390.     end;
  391.  
  392. end.
  393.